home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / ofs / ofsDisk.c < prev    next >
C/C++ Source or Header  |  1991-05-06  |  27KB  |  843 lines

  1. /* 
  2.  * ofsDisk.c --
  3.  *
  4.  *    Routines related to managing local disks under the orginial sprite
  5.  *    file system. 
  6.  *
  7.  * Copyright 1987 Regents of the University of California
  8.  * All rights reserved.
  9.  * Permission to use, copy, modify, and distribute this
  10.  * software and its documentation for any purpose and without
  11.  * fee is hereby granted, provided that the above copyright
  12.  * notice appear in all copies.  The University of California
  13.  * makes no representations about the suitability of this
  14.  * software for any purpose.  It is provided "as is" without
  15.  * express or implied warranty.
  16.  */
  17.  
  18. #ifndef lint
  19. static char rcsid[] = "$Header: /sprite/src/kernel/ofs/RCS/ofsDisk.c,v 9.12 91/01/26 15:34:42 mgbaker Exp $ SPRITE (Berkeley)";
  20. #endif not lint
  21.  
  22.  
  23. #include <sprite.h>
  24.  
  25. #include <fs.h>
  26. #include <fsutil.h>
  27. #include <fsdm.h>
  28. #include <fslcl.h>
  29. #include <fsNameOps.h>
  30. #include <fsio.h>
  31. #include <fsprefix.h>
  32. #include <fsconsist.h>
  33. #include <devDiskLabel.h>
  34. #include <dev.h>
  35. #include <devFsOpTable.h>
  36. #include <sync.h>
  37. #include <rpc.h>
  38. #include <fsioDevice.h>
  39. #include <ofs.h>
  40.  
  41. #include <stdio.h>
  42.  
  43. static Fsdm_DomainOps ofsDomainOps = {
  44.     Ofs_AttachDisk,
  45.     Ofs_DetachDisk,
  46.     Ofs_DomainWriteBack,
  47.     Ofs_RereadSummaryInfo,
  48.     Ofs_DomainInfo,
  49.     Ofs_BlockAllocate,
  50.     Ofs_GetNewFileNumber,
  51.     Ofs_FreeFileNumber,
  52.     Ofs_FileDescInit,
  53.     Ofs_FileDescFetch,
  54.     Ofs_FileDescStore,
  55.     Ofs_FileBlockRead,
  56.     Ofs_FileBlockWrite,
  57.     Ofs_FileTrunc,
  58.     Ofs_DirOpStart,
  59.     Ofs_DirOpEnd
  60. };
  61.  
  62.  
  63. static Fscache_BackendRoutines  ofsBackendRoutines = {
  64.         Fsdm_BlockAllocate,
  65.         Fsdm_FileTrunc,
  66.         Fsdm_FileBlockRead,
  67.         Fsdm_FileBlockWrite,
  68.         Ofs_ReallocBlock,
  69.         Ofs_StartWriteBack,
  70.  
  71. };
  72. static     Fscache_Backend *cacheBackendPtr = (Fscache_Backend *) NIL;
  73.  
  74.  
  75.  
  76. /*
  77.  *----------------------------------------------------------------------
  78.  *
  79.  * Ofs_Init --
  80.  *
  81.  *    Initialized code of the OFS disk storage manager module.
  82.  *
  83.  * Results:
  84.  *
  85.  * Side effects:
  86.  *    Registers OFS with Fsdm module.
  87.  *
  88.  *----------------------------------------------------------------------
  89.  */
  90. void
  91. Ofs_Init()
  92. {
  93.     Fsdm_RegisterDiskManager("OFS", Ofs_AttachDisk);
  94. }
  95.  
  96. /*
  97.  *----------------------------------------------------------------------
  98.  *
  99.  * Ofs_AttachDisk --
  100.  *
  101.  *    Try to attach a OFS disk from the specified disk.
  102.  *
  103.  * Results:
  104.  *
  105.  * Side effects:
  106.  *
  107.  *----------------------------------------------------------------------
  108.  */
  109. ReturnStatus
  110. Ofs_AttachDisk(devicePtr, localName, flags, domainNumPtr)
  111.     Fs_Device    *devicePtr;    /* Device containing file system. */
  112.     char *localName;        /* The local prefix for the domain */
  113.     int  flags;            /* Attach flags. */
  114.     int *domainNumPtr;        /* OUT: Domain number allocated. */
  115.  
  116. {
  117.     ReturnStatus status;        /* Error code */
  118.     register Address buffer;        /* Read buffer */
  119.     int headerSector;            /* Starting sector of domain header */
  120.     int numHeaderSectors;        /* Number of sectors in domain header */
  121.     int summarySector;            /* Sector of summary information. */
  122.     Ofs_SummaryInfo *summaryInfoPtr;    /* Pointer to summary info. */
  123.     Fs_IOParam    io;            /* I/O Parameter block */
  124.     Fs_IOReply    reply;            /* Results of I/O */
  125.     int        partition;
  126.     Fsdm_Domain    *domainPtr;    
  127.     Ofs_Domain    *ofsPtr;
  128.  
  129.  
  130.     headerSector = summarySector = 0;
  131.  
  132.     bzero((Address)&io, sizeof(io));
  133.     bzero((Address)&reply, sizeof(reply));
  134.     /*
  135.      * Read the zero'th sector of the partition.  It has a copy of the
  136.      * zero'th sector of the whole disk which describes how the rest of the
  137.      * domain's zero'th cylinder is layed out.
  138.      */
  139.     buffer = (Address)malloc(DEV_BYTES_PER_SECTOR * OFS_NUM_DOMAIN_SECTORS);
  140.     io.buffer = buffer;
  141.     io.length = DEV_BYTES_PER_SECTOR;
  142.     io.offset = 0;
  143.     status = (*devFsOpTable[DEV_TYPE_INDEX(devicePtr->type)].read)(devicePtr,
  144.         &io, &reply);
  145.     if (status != SUCCESS) {
  146.     free(buffer);
  147.     return(status);
  148.     }
  149.     /*
  150.      * Check for different disk formats, and figure out how the rest
  151.      * of the zero'th cylinder is layed out.
  152.      */
  153.     if (Fsdm_IsSunLabel(buffer)) {
  154.     Ofs_DomainHeader    *domainHeaderPtr = (Ofs_DomainHeader *) buffer;
  155.     int            i;
  156.     /*
  157.      * For Sun formatted disks we put the domain header well past
  158.      * the disk label and the boot program.
  159.      */
  160.     numHeaderSectors = OFS_NUM_DOMAIN_SECTORS;
  161.     io.length = DEV_BYTES_PER_SECTOR * OFS_NUM_DOMAIN_SECTORS;
  162.     for (i = 2; i < FSDM_MAX_BOOT_SECTORS + 3; i+= FSDM_BOOT_SECTOR_INC) {
  163.         io.offset = i * DEV_BYTES_PER_SECTOR;
  164.         io.length = DEV_BYTES_PER_SECTOR * OFS_NUM_DOMAIN_SECTORS;
  165.         status = (*devFsOpTable[DEV_TYPE_INDEX(devicePtr->type)].read)
  166.             (devicePtr, &io, &reply);
  167.         if (status != SUCCESS) {
  168.         free(buffer);
  169.         return(status);
  170.         }
  171.         if (domainHeaderPtr->magic == OFS_DOMAIN_MAGIC) {
  172.         headerSector = i;
  173.         summarySector = i - 1;
  174.             break;
  175.         }
  176.     }
  177.     if (i >= FSDM_MAX_BOOT_SECTORS + 3) {
  178.         free(buffer);
  179.         return(FAILURE);
  180.     }
  181.     } else if (Fsdm_IsSpriteLabel(buffer)) {
  182.     register Fsdm_DiskHeader *diskHeaderPtr;
  183.     diskHeaderPtr = (Fsdm_DiskHeader *)buffer;
  184.     headerSector = diskHeaderPtr->domainSector;
  185.     numHeaderSectors = diskHeaderPtr->numDomainSectors;
  186.     summarySector = diskHeaderPtr->summarySector;
  187.     } else {
  188.     io.buffer = buffer;
  189.     io.length = DEV_BYTES_PER_SECTOR;
  190.     io.offset = DEC_LABEL_SECTOR * DEV_BYTES_PER_SECTOR;
  191.     status = (*devFsOpTable[DEV_TYPE_INDEX(devicePtr->type)].read)
  192.         (devicePtr, &io, &reply);
  193.     if (status != SUCCESS) {
  194.         free(buffer);
  195.         return(status);
  196.     }
  197.     if (Fsdm_IsDecLabel(buffer)){
  198.         register Dec_DiskLabel *decLabelPtr;
  199.         decLabelPtr = (Dec_DiskLabel *)buffer;
  200.         headerSector = decLabelPtr->domainSector;
  201.         numHeaderSectors = decLabelPtr->numDomainSectors;
  202.         summarySector = decLabelPtr->summarySector;
  203.     } else {
  204.         printf("Ofs_AttachDisk: No disk header\n");
  205.         free(buffer);
  206.         return(FAILURE);
  207.     }
  208.     }
  209.     /*
  210.      * Read in summary information.
  211.      */
  212.     io.length = DEV_BYTES_PER_SECTOR;
  213.     io.offset = summarySector * DEV_BYTES_PER_SECTOR;
  214.     status = (*devFsOpTable[DEV_TYPE_INDEX(devicePtr->type)].read)
  215.         (devicePtr, &io, &reply); 
  216.     if (status != SUCCESS) {
  217.     free(buffer);
  218.     return(status);
  219.     }
  220.     summaryInfoPtr = (Ofs_SummaryInfo *) buffer;
  221.  
  222.     /*
  223.      * Read the domain header and save it with the domain state.
  224.      */
  225.     buffer = (Address)malloc(DEV_BYTES_PER_SECTOR * numHeaderSectors);
  226.     io.buffer = buffer;
  227.     io.length = numHeaderSectors * DEV_BYTES_PER_SECTOR;
  228.     io.offset = headerSector * DEV_BYTES_PER_SECTOR;
  229.     status = (*devFsOpTable[DEV_TYPE_INDEX(devicePtr->type)].read)(devicePtr,
  230.         &io, &reply);
  231.     if (status != SUCCESS) {
  232.     free((char *) summaryInfoPtr);
  233.     free(buffer);
  234.     return(status);
  235.     } else if (((Ofs_DomainHeader *)buffer)->magic != OFS_DOMAIN_MAGIC) {
  236.     free((char *) summaryInfoPtr);
  237.     free(buffer);
  238.     return(FAILURE);
  239.     }
  240.     /*
  241.      * Make the domain flag positive to inform caller that this is an
  242.      * OFS file system even if the mount fails.
  243.      */
  244.     *domainNumPtr = 1;
  245.     /* 
  246.      * Verify the device specification by checking the partition
  247.      * number kept in the domain header. 
  248.      */
  249.     partition = ((Ofs_DomainHeader *)buffer)->device.unit;
  250.     if (partition >= 0 && partition < FSDM_NUM_DISK_PARTS) {
  251.     if ((devicePtr->unit % FSDM_NUM_DISK_PARTS) != partition) {
  252.         printf("Ofs_AttachDisk: partition mis-match, arg %d disk %d\n",
  253.               devicePtr->unit, partition);
  254.         free((char *) summaryInfoPtr);
  255.         free(buffer);
  256.         return(FAILURE);
  257.     }
  258.     }
  259.     status = Fsdm_InstallDomain(summaryInfoPtr->domainNumber,
  260.         ((Ofs_DomainHeader *)buffer)->device.serverID, 
  261.         localName, flags, &domainPtr);
  262.     if (status != SUCCESS) {
  263.     if (status == FS_FILE_BUSY) {
  264.         if (domainPtr->flags & FSDM_DOMAIN_ATTACH_BOOT) {
  265.         domainPtr->flags &= ~FSDM_DOMAIN_ATTACH_BOOT;
  266.         summaryInfoPtr->flags &=  ~OFS_DOMAIN_JUST_CHECKED;
  267.         printf("Ofs_AttachDisk: clearing just-checked bit\n");
  268.         if ((flags & FS_ATTACH_READ_ONLY) == 0) {
  269.             io.buffer = (char *) summaryInfoPtr;
  270.             io.length = DEV_BYTES_PER_SECTOR;
  271.             io.offset = summarySector * DEV_BYTES_PER_SECTOR;
  272.             status = 
  273.              (*devFsOpTable[DEV_TYPE_INDEX(devicePtr->type)].write)
  274.                     (devicePtr, &io, &reply);
  275.             if (status != SUCCESS) {
  276.             panic( 
  277.         "Ofs_AttachDisk: Summary write failed, status %x\n", status);
  278.             }
  279.         }
  280.         }
  281.         status = FS_DOMAIN_UNAVAILABLE;
  282.     }
  283.     free((char *) summaryInfoPtr);
  284.     free(buffer);
  285.     return status;
  286.     }
  287.     if (cacheBackendPtr == (Fscache_Backend *) NIL) {
  288.     cacheBackendPtr = 
  289.         Fscache_RegisterBackend(&ofsBackendRoutines,(ClientData) 0, 0);
  290.     }
  291.  
  292.     ofsPtr = (Ofs_Domain *) malloc(sizeof(Ofs_Domain));
  293.     bzero((char *) ofsPtr, sizeof(Ofs_Domain));
  294.  
  295.     domainPtr->backendPtr = cacheBackendPtr;
  296.     domainPtr->domainOpsPtr = &ofsDomainOps;
  297.     domainPtr->clientData = (ClientData) ofsPtr;
  298.  
  299.     ofsPtr->domainPtr = domainPtr;
  300.     ofsPtr->headerPtr = (Ofs_DomainHeader *) buffer;
  301.     ofsPtr->summaryInfoPtr = summaryInfoPtr;
  302.     ofsPtr->summarySector = summarySector;
  303.     ofsPtr->blockDevHandlePtr = (DevBlockDeviceHandle *) (devicePtr->data);
  304.     /*
  305.      * Fix up the device information in the domain header
  306.      * as this is used by the block I/O routines.
  307.      */
  308.     ofsPtr->headerPtr->device.unit = devicePtr->unit;
  309.     ofsPtr->headerPtr->device.type = devicePtr->type;
  310.     ofsPtr->headerPtr->device.data = devicePtr->data;
  311.  
  312.     /*
  313.      * After reading the low level header information from the disk we
  314.      * install the domain into the set of active domains and initialize
  315.      * things for block I/O.
  316.      */
  317.  
  318.     status = OfsIOInit(domainPtr);
  319.     if (status != SUCCESS) {
  320.     printf( "Ofs_InitializeDomain: can't initialize block I/O %x\n",
  321.         status);
  322.     domainPtr->flags |= FSDM_DOMAIN_DOWN;
  323.     return(status);
  324.     }
  325.     /*
  326.      * Set the domainNumber in the summary info so next time we will be
  327.      * mounted under the same domain number.
  328.      */
  329.     summaryInfoPtr->domainNumber = domainPtr->domainNumber;
  330.     *domainNumPtr = domainPtr->domainNumber;
  331.  
  332.     /*
  333.      * Finally mark the domain to indicate that if we go down hard,
  334.      * clean recovery of this domain is impossible.
  335.      */
  336.     if ((summaryInfoPtr->flags & OFS_DOMAIN_NOT_SAFE) == 0) {
  337.     summaryInfoPtr->flags |= OFS_DOMAIN_ATTACHED_CLEAN;
  338.     } else {
  339.     summaryInfoPtr->flags &= ~OFS_DOMAIN_ATTACHED_CLEAN;
  340.     }
  341.     summaryInfoPtr->flags |= OFS_DOMAIN_NOT_SAFE |
  342.                     OFS_DOMAIN_TIMES_VALID;
  343.     if (!(flags & FS_DEFAULT_DOMAIN)) {
  344.     summaryInfoPtr->flags &= ~OFS_DOMAIN_JUST_CHECKED;
  345.     }
  346.     summaryInfoPtr->attachSeconds = Fsutil_TimeInSeconds();
  347.     if ((flags & FS_ATTACH_READ_ONLY) == 0) {
  348.     status = OfsWriteBackSummaryInfo(ofsPtr);
  349.     if (status != SUCCESS) {
  350.         panic( "Ofs_AttachDisk: Summary write failed, status %x\n", status);
  351.     }
  352.     } 
  353.     return status;
  354.  
  355. }
  356.  
  357. /*
  358.  *----------------------------------------------------------------------
  359.  *
  360.  * OfsIOInit --
  361.  *
  362.  *    Initialize a particular local domain for I/O.
  363.  *
  364.  * Results:
  365.  *    Error code returned from initializing data block and file
  366.  *    descriptor allocation.
  367.  *
  368.  * Side effects:
  369.  *    Physical file handle for the domain is initialized.
  370.  *
  371.  *----------------------------------------------------------------------
  372.  */
  373.  
  374. ReturnStatus
  375. OfsIOInit(domainPtr)
  376.     Fsdm_Domain    *domainPtr;
  377. {
  378.     register    Ofs_Domain    *ofsPtr;
  379.     ReturnStatus        status;
  380.     Fscache_Attributes        attr;
  381.     int            domainNumber;
  382.  
  383.     ofsPtr = OFS_PTR_FROM_DOMAIN(domainPtr);
  384.     domainNumber = domainPtr->domainNumber;
  385.     /*
  386.      * Initialize the file handle used for raw I/O, i.e. for file descriptors,
  387.      * the bitmaps, and indirect blocks.
  388.      */
  389.  
  390.     bzero((Address)&ofsPtr->physHandle, sizeof(ofsPtr->physHandle));
  391.     ofsPtr->physHandle.hdr.fileID.major = domainNumber;
  392.     ofsPtr->physHandle.hdr.fileID.minor = 0;
  393.     ofsPtr->physHandle.hdr.fileID.type = FSIO_LCL_FILE_STREAM;
  394.     ofsPtr->physHandle.descPtr = (Fsdm_FileDescriptor *)NIL;
  395.  
  396.     bzero((Address)&attr, sizeof(attr));
  397.     attr.lastByte = 0x7fffffff;
  398.     Fscache_FileInfoInit(&ofsPtr->physHandle.cacheInfo,
  399.             (Fs_HandleHeader *) &ofsPtr->physHandle,
  400.             0, TRUE, &attr, domainPtr->backendPtr);
  401.  
  402.     status = OfsBlockAllocInit(ofsPtr);
  403.     if (status != SUCCESS) {
  404.     printf( "Block Alloc init failed for domain %d\n",
  405.         domainNumber);
  406.     return(status);
  407.     }
  408.     status = OfsFileDescAllocInit(ofsPtr);
  409.     if (status != SUCCESS) {
  410.     printf( "File Desc alloc init failed for domain %d\n",
  411.         domainNumber);
  412.     return(status);
  413.     }
  414.     return(status);
  415. }
  416.  
  417.  
  418.  
  419. /*
  420.  *----------------------------------------------------------------------
  421.  *
  422.  * Ofs_DetachDisk --
  423.  *
  424.  *    Remove a local domain from the set of accessible domains.
  425.  *
  426.  * Results:
  427.  *    SUCCESS if the domain was already attached and all the outstanding
  428.  *    file handles could be recalled.
  429.  *
  430.  * Side effects:
  431.  *    Clears the prefix table entry for the domain.
  432.  *
  433.  *----------------------------------------------------------------------
  434.  */
  435. ReturnStatus
  436. Ofs_DetachDisk(domainPtr)
  437.     Fsdm_Domain    *domainPtr;
  438. {
  439.     register Ofs_Domain    *ofsPtr = OFS_PTR_FROM_DOMAIN(domainPtr);
  440.     Ofs_DomainHeader    *headerPtr;
  441.     int            i;
  442.     ReturnStatus    status;
  443.     int            blocksLeft, blocksSkipped;
  444.  
  445.     /*
  446.      * Write all dirty blocks, bitmaps, etc. to disk and take the
  447.      * domain down.
  448.      */
  449.     Fscache_WriteBack(-1, &blocksLeft, FALSE);    /* Write back the cache. */
  450.     headerPtr = ofsPtr->headerPtr;
  451. #ifdef SOSP91
  452.     ofsPtr->physHandle.cacheInfo.flags |= FSCACHE_DETACH;
  453. #endif SOSP91
  454.     Fscache_FileWriteBack(&ofsPtr->physHandle.cacheInfo,
  455.         headerPtr->fileDescOffset,
  456.         headerPtr->fileDescOffset + 
  457.         (headerPtr->numFileDesc / FSDM_FILE_DESC_PER_BLOCK) + 1,
  458.         FSCACHE_WRITE_BACK_AND_INVALIDATE, &blocksSkipped);
  459.     Fsdm_DomainWriteBack(ofsPtr->physHandle.hdr.fileID.major, FALSE, TRUE);
  460.     /* Write back domain info. */
  461.     /*
  462.      * We successfully brought down the disk, so mark it as OK.
  463.      * The detach time is noted in order to track how long disks are available.
  464.      */
  465.     ofsPtr->summaryInfoPtr->flags &= ~OFS_DOMAIN_NOT_SAFE;
  466.     ofsPtr->summaryInfoPtr->flags &= ~OFS_DOMAIN_JUST_CHECKED;
  467.     ofsPtr->summaryInfoPtr->detachSeconds = Fsutil_TimeInSeconds();
  468.     status = OfsWriteBackSummaryInfo(ofsPtr);
  469.     if (status != SUCCESS) {
  470.     panic( "Ofs_DetachDisk: Summary write failed, status %x\n",
  471.             status);
  472.     }
  473.  
  474.     /*
  475.      * Free up resources for the domain.
  476.      */
  477.     Sync_LockClear(&ofsPtr->dataBlockLock);
  478.     Sync_LockClear(&ofsPtr->fileDescLock);
  479.     free((Address)ofsPtr->headerPtr);
  480.     free((Address)ofsPtr->summaryInfoPtr);
  481.     free((Address)ofsPtr->dataBlockBitmap);
  482.     free((Address)ofsPtr->cylinders);
  483.     for (i = 0; i < OFS_NUM_FRAG_SIZES; i++) {
  484.     List_Links    *fragList;
  485.     OfsFragment    *fragPtr;
  486.     fragList = ofsPtr->fragLists[i];
  487.     while (!List_IsEmpty(fragList)) {
  488.         fragPtr = (OfsFragment *)List_First(fragList);
  489.         List_Remove((List_Links *)fragPtr);
  490.         free((Address)fragPtr);
  491.     }
  492.     free((Address)fragList);
  493.     }
  494.     free((Address)ofsPtr->fileDescBitmap);
  495.  
  496.     return(SUCCESS);
  497. }
  498.  
  499.  
  500. /*
  501.  *----------------------------------------------------------------------
  502.  *
  503.  * Ofs_DomainWriteBack --
  504.  *
  505.  *    Force all domain information to disk.
  506.  *
  507.  * Results:
  508.  *    Error code if the write failed.
  509.  *
  510.  * Side effects:
  511.  *    None.
  512.  *
  513.  *----------------------------------------------------------------------
  514.  */
  515. ReturnStatus
  516. Ofs_DomainWriteBack(domainPtr, shutdown)
  517.     Fsdm_Domain    *domainPtr;    /* Domain to writeback. */
  518.     Boolean    shutdown;    /* TRUE if are syncing to shutdown the system.*/
  519. {
  520.     register    Ofs_Domain    *ofsPtr = OFS_PTR_FROM_DOMAIN(domainPtr);
  521.     ReturnStatus        status1, status2;
  522.  
  523.     status1 = OfsWriteBackDataBlockBitmap(ofsPtr);
  524.     status2 = OfsWriteBackFileDescBitmap(ofsPtr);
  525.     if (shutdown && status1 == SUCCESS && status2 == SUCCESS) {
  526.     ofsPtr->summaryInfoPtr->flags &= ~OFS_DOMAIN_NOT_SAFE;
  527.     ofsPtr->summaryInfoPtr->detachSeconds = Fsutil_TimeInSeconds();
  528.     } else {
  529.     ofsPtr->summaryInfoPtr->flags |= OFS_DOMAIN_NOT_SAFE;
  530.     }
  531.     (void)OfsWriteBackSummaryInfo(ofsPtr);
  532.     return (status1 == SUCCESS) ? status2 : status1;
  533. }
  534.  
  535.  
  536. /*
  537.  *----------------------------------------------------------------------
  538.  * The following routines are used by device drivers to map from block
  539.  * and sector numbers to disk addresses.  There are two sets, one for
  540.  * drivers that use logical sector numbers (i.e. SCSI) and the other
  541.  * for <cyl,head,sector> format disk addresses.
  542.  *----------------------------------------------------------------------
  543.  */
  544.  
  545. /*
  546.  *----------------------------------------------------------------------
  547.  *
  548.  * OfsBlocksToSectors --
  549.  *
  550.  *    Convert from block indexes (actually, fragment indexes) to
  551.  *    sectors using the geometry information on the disk.  This
  552.  *    is a utility for block device drivers.
  553.  *
  554.  * Results:
  555.  *    The sector number that corresponds to the fragment index.
  556.  *    The caller has to make sure that its I/O doesn't cross a
  557.  *    filesystem block boundary.
  558.  *
  559.  * Side effects:
  560.  *    None.
  561.  *
  562.  *----------------------------------------------------------------------
  563.  */
  564. #define SECTORS_PER_FRAG    (FS_FRAGMENT_SIZE / DEV_BYTES_PER_SECTOR)
  565. int
  566. OfsBlocksToSectors(fragNumber, geoPtr)
  567.     int fragNumber;    /* Fragment index to map into block index */
  568.     register Ofs_Geometry *geoPtr;    /* ClientData from the device info */
  569. {
  570.     register int sectorNumber;    /* The sector corresponding to the fragment */
  571.     register int cylinder;    /* The cylinder number of the fragment */
  572.     register int rotationalSet;    /* The rotational set with cylinder of frag */
  573.     register int blockNumber;    /* The block number within rotational set */
  574.  
  575.     blockNumber        = fragNumber / FS_FRAGMENTS_PER_BLOCK;
  576.     cylinder        = blockNumber / geoPtr->blocksPerCylinder;
  577.     /*
  578.      * This is the old way of doing things.  We have to deal with rotational
  579.      * sets and the like.
  580.      */
  581.     if (geoPtr->rotSetsPerCyl > 0) {    
  582.     
  583.     blockNumber        -= cylinder * geoPtr->blocksPerCylinder;
  584.     rotationalSet    = blockNumber / geoPtr->blocksPerRotSet;
  585.     blockNumber        -= rotationalSet * geoPtr->blocksPerRotSet;
  586.     
  587.     sectorNumber = geoPtr->sectorsPerTrack * geoPtr->numHeads * cylinder +
  588.               geoPtr->sectorsPerTrack * geoPtr->tracksPerRotSet *
  589.               rotationalSet +
  590.               geoPtr->blockOffset[blockNumber];
  591.     sectorNumber += (fragNumber % FS_FRAGMENTS_PER_BLOCK) * 
  592.             SECTORS_PER_FRAG;
  593.     } else if (geoPtr->rotSetsPerCyl == OFS_SCSI_MAPPING) {
  594.     /*
  595.      * The new way is to map blocks from the start of the disk without
  596.      * regard for rotational sets.  There is essentially one rotational
  597.      * set per disk.
  598.      */
  599.     sectorNumber = geoPtr->sectorsPerTrack * geoPtr->numHeads * cylinder +
  600.             fragNumber * SECTORS_PER_FRAG - cylinder * 
  601.             geoPtr->blocksPerCylinder * FS_FRAGMENTS_PER_BLOCK *
  602.             SECTORS_PER_FRAG;
  603.     } else {
  604.     panic("Unknown mapping in domain geometry information\n");
  605.     sectorNumber = -1;
  606.     }
  607.     return(sectorNumber);
  608. }
  609.  
  610. /*
  611.  *----------------------------------------------------------------------
  612.  *
  613.  * Ofs_BlocksToDiskAddr --
  614.  *
  615.  *    Convert from block indexes (actually, fragment indexes) to
  616.  *    disk address (head, cylinder, sector) using the geometry information
  617.  *     on the disk.  This is a utility for block device drivers.
  618.  *
  619.  * Results:
  620.  *    The disk address that corresponds to the disk address.
  621.  *    The caller has to make sure that its I/O doesn't cross a
  622.  *    filesystem block boundary.
  623.  *
  624.  * Side effects:
  625.  *    None.
  626.  *
  627.  *----------------------------------------------------------------------
  628.  */
  629. void
  630. Ofs_BlocksToDiskAddr(fragNumber, data, diskAddrPtr)
  631.     int fragNumber;    /* Fragment index to map into block index */
  632.     ClientData data;    /* ClientData from the device info */
  633.     Dev_DiskAddr *diskAddrPtr;
  634. {
  635.     register Ofs_Geometry *geoPtr;
  636.     register int sectorNumber;    /* The sector corresponding to the fragment */
  637.     register int cylinder;    /* The cylinder number of the fragment */
  638.     register int rotationalSet;    /* The rotational set with cylinder of frag */
  639.     register int blockNumber;    /* The block number within rotational set */
  640.  
  641.     geoPtr         = (Ofs_Geometry *)data;
  642.     /*
  643.      * Map to block number because the rotational sets are laid out
  644.      * relative to blocks.  After that the cylinder is easy because we know
  645.      * blocksPerCylinder.  To get the head and sector we first get the
  646.      * rotational set (described in fsDisk.h) of the block and the
  647.      * block's sector offset (relative to the rotational set!).  This complex
  648.      * algorithm crops up because there isn't necessarily an even number
  649.      * of blocks per track.  The 'blockOffset' array in the geometry gives
  650.      * a sector index of each successive block in a rotational set. Finally,
  651.      * we can use the sectorsPerTrack to get the head and sector.
  652.      */
  653.     blockNumber        = fragNumber / FS_FRAGMENTS_PER_BLOCK;
  654.     cylinder        = blockNumber / geoPtr->blocksPerCylinder;
  655.     blockNumber        -= cylinder * geoPtr->blocksPerCylinder;
  656.     diskAddrPtr->cylinder = cylinder;
  657.  
  658.     rotationalSet    = blockNumber / geoPtr->blocksPerRotSet;
  659.     blockNumber        -= rotationalSet * geoPtr->blocksPerRotSet;
  660. /*
  661.  * The follow statment had to be broken into two because the compiler used
  662.  * register d2 to do the modulo operation, but wasn't saving its value.
  663.  */
  664.     sectorNumber    = geoPtr->sectorsPerTrack * geoPtr->tracksPerRotSet *
  665.               rotationalSet + geoPtr->blockOffset[blockNumber];
  666.     sectorNumber    +=
  667.             (fragNumber % FS_FRAGMENTS_PER_BLOCK) * SECTORS_PER_FRAG;
  668.  
  669.     diskAddrPtr->head    = sectorNumber / geoPtr->sectorsPerTrack;
  670.     diskAddrPtr->sector = sectorNumber -
  671.               diskAddrPtr->head * geoPtr->sectorsPerTrack;
  672. }
  673.  
  674. /*
  675.  *----------------------------------------------------------------------
  676.  *
  677.  * Ofs_SectorsToRawDiskAddr --
  678.  *
  679.  *      Convert from a sector offset to a raw disk address (cyl, head,
  680.  *      sector) using the geometry information on the disk.  This is a
  681.  *      utility for raw device drivers and does not pay attention to the
  682.  *      rotational position of filesystem disk blocks.
  683.  *
  684.  *    This should be moved to Dev
  685.  *
  686.  * Results:
  687.  *    The disk address that corresponds exactly to the byte offset.
  688.  *
  689.  * Side effects:
  690.  *    None.
  691.  *
  692.  *----------------------------------------------------------------------
  693.  */
  694. int
  695. Ofs_SectorsToRawDiskAddr(sector, numSectors, numHeads, diskAddrPtr)
  696.     int sector;        /* Sector number (counting from zero 'til the total
  697.              * number of sectors in the disk) */
  698.     int numSectors;    /* Number of sectors per track */
  699.     int numHeads;    /* Number of heads on the disk */
  700.     Dev_DiskAddr *diskAddrPtr;
  701. {
  702.     register int sectorsPerCyl;    /* The rotational set with cylinder of frag */
  703.  
  704.     sectorsPerCyl        = numSectors * numHeads;
  705.     diskAddrPtr->cylinder    = sector / sectorsPerCyl;
  706.     sector            -= diskAddrPtr->cylinder * sectorsPerCyl;
  707.     diskAddrPtr->head        = sector / numSectors;
  708.     diskAddrPtr->sector        = sector - numSectors * diskAddrPtr->head;
  709.     return 0;
  710. }
  711.  
  712.  
  713. /*
  714.  *----------------------------------------------------------------------
  715.  *
  716.  * Ofs_RereadSummaryInfo --
  717.  *
  718.  *    Reread the summary sector associated with the prefix and update
  719.  *    the domain information. This should be called if the summary
  720.  *    sector on the disk has been changed since the domain was attached.
  721.  *
  722.  * Results:
  723.  *    SUCCESS if the summary sector was read correctly and the 
  724.  *    information was updated
  725.  *
  726.  * Side effects:
  727.  *    The summary sector information associated with the domain is
  728.  *    updated.
  729.  *
  730.  *----------------------------------------------------------------------
  731.  */
  732.  
  733. ReturnStatus
  734. Ofs_RereadSummaryInfo(domainPtr)
  735.     Fsdm_Domain        *domainPtr;    /* Domain to reread summary for. */
  736. {
  737.     register Ofs_Domain    *ofsPtr = OFS_PTR_FROM_DOMAIN(domainPtr);
  738.     ReturnStatus    status;
  739.     Fs_Device        *devicePtr;
  740.     Fs_IOParam        io;
  741.     Fs_IOReply        reply;
  742.     char        buffer[DEV_BYTES_PER_SECTOR];
  743.  
  744.     bzero((Address)&io, sizeof(io));
  745.     bzero((Address)&reply, sizeof(reply));
  746.     devicePtr = &(ofsPtr->headerPtr->device);
  747.     io.buffer = buffer;
  748.     io.length = DEV_BYTES_PER_SECTOR;
  749.     io.offset = ofsPtr->summarySector * DEV_BYTES_PER_SECTOR;
  750.     status = (*devFsOpTable[DEV_TYPE_INDEX(devicePtr->type)].read)
  751.         (devicePtr, &io, &reply); 
  752.     /*
  753.      * Copy information from the buffer.
  754.      */
  755.     if (status == SUCCESS) { 
  756.     bcopy(buffer, (char *)ofsPtr->summaryInfoPtr, reply.length);
  757.     }
  758.     return status;
  759. }
  760.  
  761.  
  762. /*
  763.  *----------------------------------------------------------------------
  764.  *
  765.  * Ofs_DirOpStart --
  766.  *
  767.  *    Mark the start of a directory operation on an OFS file system.
  768.  *    Since OFS uses fscheck to do crash recovery, this is a noop.
  769.  *
  770.  * Results:
  771.  *    NIL
  772.  *    
  773.  *
  774.  * Side effects:
  775.  *    None.
  776.  *
  777.  *----------------------------------------------------------------------
  778.  */
  779.  
  780. ClientData
  781. Ofs_DirOpStart(domainPtr, opFlags, name, nameLen, fileNumber, fileDescPtr,
  782.          dirFileNumber, dirOffset, dirFileDescPtr)
  783.     Fsdm_Domain    *domainPtr;    /* Domain containing the object being modified.
  784.                  */
  785.     int        opFlags;    /* Operation code and flags. See fsdm.h for
  786.                  * definitions. */
  787.     char    *name;        /* Name of object being operated on. */
  788.     int        nameLen;    /* Length in characters of name. */
  789.     int        fileNumber;    /* File number of objecting being operated on.*/
  790.     Fsdm_FileDescriptor *fileDescPtr; /* FileDescriptor object being operated on
  791.                        * before operation starts. */
  792.     int        dirFileNumber;    /* File number of directory containing object.*/
  793.     int        dirOffset;    /* Byte offset into directory of the directory
  794.                  * entry containing operation. */
  795.     Fsdm_FileDescriptor *dirFileDescPtr; /* FileDescriptor of directory before
  796.                       * operation starts. */
  797. {
  798.     return (ClientData) -1;
  799. }
  800.  
  801. /*
  802.  *----------------------------------------------------------------------
  803.  *
  804.  * Ofs_DirOpEnd --
  805.  *
  806.  *    Mark the end of a directory operation on an OFS file system.
  807.  *    Since OFS uses fscheck to do crash recovery, this is a noop.
  808.  *
  809.  * Results:
  810.  *    None
  811.  *    
  812.  *
  813.  * Side effects:
  814.  *    None.
  815.  *
  816.  *----------------------------------------------------------------------
  817.  */
  818.  
  819. void
  820. Ofs_DirOpEnd(domainPtr, clientData, status, opFlags, name, nameLen, 
  821.         fileNumber,  fileDescPtr, dirFileNumber, dirOffset, 
  822.         dirFileDescPtr)
  823.     Fsdm_Domain    *domainPtr;    /* Domain containing the object modified. */
  824.     ClientData    clientData;    /* ClientData as returned by DirOpStart. */
  825.     ReturnStatus status;    /* Return status of the operation, SUCCESS if
  826.                  * operation succeeded. FAILURE otherwise. */
  827.     int        opFlags;    /* Operation code and flags. See fsdm.h for
  828.                  * definitions. */
  829.     char    *name;        /* Name of object being operated on. */
  830.     int        nameLen;    /* Length in characters of name. */
  831.     int        fileNumber;    /* File number of objecting being operated on.*/
  832.     Fsdm_FileDescriptor *fileDescPtr; /* FileDescriptor object after
  833.                       * operation.*/
  834.     int        dirFileNumber;    /* File number of directory containing object.*/
  835.     int        dirOffset;    /* Byte offset into directory of the directory
  836.                  * entry containing operation. */
  837.     Fsdm_FileDescriptor *dirFileDescPtr; /* FileDescriptor of directory after
  838.                       * operation. */
  839. {
  840.     return;
  841. }
  842.  
  843.